package org.kineticsproject.devices.parsers;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringTokenizer;

import data.DataFactory;
import data.DisplacementSample;
import data.Exercise;
import data.PositionSample;

public class GarminGPSParser extends Parser {

	private FileInputStream fis;
	private DataInputStream dis;
    private File            f;
   // private ErrorHandler	eh;
    private StringTokenizer strtok;
    
	@Override
	public boolean process(Exercise exercise, String filename, String newdate,
			long timeOffset) {
		  int 				i 						= 0;
		  boolean 			result 					= true;  
		 // FileErrorInfo 	fei 					= new FileErrorInfo();
		  //ErrorInfo         ei          			= new ErrorInfo();
		  data.DataLog      positionDataLog 		= DataFactory.eINSTANCE.createDataLog();
		  data.DataLog      displacementDataLog 	= DataFactory.eINSTANCE.createDataLog();
		  		  
		  exercise.getDatalogs().add(displacementDataLog);
		  exercise.getDatalogs().add(positionDataLog);
		  //exerciseadd(displacementDataLog);
		  //dataLogSet.add(positionDataLog);
		  
		//  ErrorInfo     ei  = new ErrorInfo();
		 
		  /* Open File */
			 try 
			 {
				 //eh  = new ErrorHandler();
				 f 	 = new File(filename);
				 fis = new FileInputStream(f);
				 dis = new DataInputStream(fis);
			 }
			 catch(IOException ex)
			 {
				 //eh.process(ErrorHandler.FILENOTFOUND_EXCEPTION,fei); 
			 }
			 
		 try {
		       while (i < 9) // skip header
		       {
		    	   //System.out.println(dis.readLine());
		    	   dis.readLine();
		    	   ++i;
		       }
			 }
		 catch(IOException ex)
		 {
			// eh.process(ErrorHandler.FILEREAD_EXCEPTION,fei);
		 }
		 
		 i = 0;
		 try {
	       while ((dis.available() != 0) )
	       {
	    
	    	   String str;
	    	   String sLatDegrees;
	    	   String sLatMinutes;
	    	   String sAltitude;
	    	   String sLonDegrees;
	    	   String sLonMinutes;
	    	   String sDate;
	    	   String sTime;
	    	   String sTimeAMPM;
	    	   String sAltitudeUnits;
	    	   String sLegLength;
	    	   String sLegLengthUnits;
	    	   String sLegTime;
	    	   String sLegSpeed;
	    	   String sLegSpeedUnits;
	    	   String sLegHeading;
	    	   Date   date;
	    	   
	    	   double dfLatDegrees;
	    	   double dfLonDegrees;
	    	//   int    iAltitude;
	    	   PositionSample 		psample;
	    	   DisplacementSample	dsample;
	    	   
	    	   str = dis.readLine();
	    	   i++;
	    	   strtok = new StringTokenizer(str);
	    	//   while (strtok.hasMoreTokens())
	    	   {
	    		   
	    		   try
	    		   {
	    		   						strtok.nextToken(); // Trackpoint
	    		   sLatDegrees		= 	strtok.nextToken(); // Lat Degrees
	    		   sLatMinutes  	= 	strtok.nextToken(); // Lat Minutes
	    		   sLonDegrees  	=   strtok.nextToken(); // Lon Degrees
	    		   sLonMinutes  	=   strtok.nextToken(); // Lon Minutes
	    		   sDate 			=   strtok.nextToken(); // Date
	    		   sTime        	=   strtok.nextToken(); // Time
	    		   sTimeAMPM    	=   strtok.nextToken(); // Time AM/PM
	    		   sAltitude 		=   strtok.nextToken(); // Altitude
	    		   sAltitudeUnits 	=	strtok.nextToken(); // Meters / Feet
	    		   sLegLength       =   strtok.nextToken(); // Length of leg
	    		   sLegLengthUnits	= 	strtok.nextToken(); // Meters / Feet
	    		   sLegTime			=   strtok.nextToken(); // Elapsed time for Leg
	    		   sLegSpeed		=   strtok.nextToken(); // Speed for leg
	    		   sLegSpeedUnits	= 	strtok.nextToken(); // mph, kph
	    		   sLegHeading		=	strtok.nextToken(); // heading for Leg in degrees (0 to 360)

	    		   if (sLatDegrees.charAt(0) == 'S')
	    		   {
	    			   dfLatDegrees = -StringtoInt(sLatDegrees.substring(1));
	    			   dfLatDegrees = (dfLatDegrees)-(Double.valueOf(sLatMinutes).doubleValue()/60.0);
	    		   }
	    		   else
			   	   {
	    			   dfLatDegrees = StringtoInt(sLatDegrees.substring(1));
	    			   dfLatDegrees = (dfLatDegrees)+(Double.valueOf(sLatMinutes).doubleValue()/60.0);   		   
				   }
	    		  
	    		   if (sLonDegrees.charAt(0) == 'W')
	    		   {
	    			   dfLonDegrees = -StringtoInt(sLonDegrees.substring(1));
	    			   dfLonDegrees = (dfLonDegrees)-(Double.valueOf(sLonMinutes).doubleValue()/60.0);
	    		   }
	    		   else
	    		   {
	    			   dfLonDegrees = StringtoInt(sLonDegrees.substring(1));
	    			   dfLonDegrees = (dfLonDegrees)+(Double.valueOf(sLonMinutes).doubleValue()/60.0);    			   
	    		   }
	    		   
	    //		   iAltitude = Integer.valueOf(sAltitude).intValue();
	    		       
	    		   
	    	//	   System.out.println("Lat: "+dfLatDegrees+" Lon: "+dfLonDegrees);
	    		   
	    		   psample = DataFactory.eINSTANCE.createPositionSample();
	    		   dsample = DataFactory.eINSTANCE.createDisplacementSample();
	    	//	   date    = new Date();
	    		   StringTokenizer strtokTime = new StringTokenizer(sTime,":");
	    		   
	    		    
	    		   String sTimeHour;
	    		   String sTimeMinutes;
	    		   String sTimeSeconds;
	    		   
	    		   if (sTimeAMPM.compareTo("PM") == 0)  // convert to 24hr clock
	    		   sTimeHour 	= String.valueOf((Integer.valueOf(strtokTime.nextToken()).intValue()%12)+12);
	    		   else
	    			   sTimeHour 	= (String.valueOf(Integer.valueOf(strtokTime.nextToken()).intValue()%12));
	    		   
	    		   sTimeMinutes	= strtokTime.nextToken();
	    		   sTimeSeconds  = strtokTime.nextToken();
	    		   
	    		   SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	    		//	   System.out.println(/*2006-04-11*/newdate+" "+sTimeHour+":"+sTimeMinutes+":"+sTimeSeconds);
	    			   
	    		   try
	    		   {
	    		   Date sampleDate = simpleDateFormat.parse(/*"2006-04-11*/newdate+" "+sTimeHour+":"+sTimeMinutes+":"+sTimeSeconds);
	    		 //  System.out.println("Parsed: "+sampleDate.toString());
	    		   
	    		   Timestamp dtimestamp = new Timestamp(sampleDate.getTime()+timeOffset);
	    		   dsample.setTimestamp(dtimestamp);
	    		   Timestamp postimestamp = new Timestamp(sampleDate.getTime()+timeOffset);
	    		   
	    		   psample.setTimestamp(postimestamp); 
	    		  // System.out.println("Mili: "+psample.getTimestamp().toString());
	    		   }
	    		   catch (ParseException e)
	    		   {
	    			  // eh.process(ErrorHandler.DATE_PARSE_EXCEPTION,ei);
	    		   }
	    		   
	    		   
	    		   /* Store data in displacementSample */
	    		   dsample.setHeading(StringtoInt(sLegHeading.substring(0,sLegHeading.length()-1)));
	    		   dsample.setSpeed((float)UnitConverter.MilestoKilometers(StringtoInt(sLegSpeed)));
	    		//   dsample.setDisplacement((int)parser.UnitConverter.FeettoCentimeters(StringtoInt(sLegLength)));
	    		   dsample.setDisplacement((int)(StringtoInt(sLegLength)));
	 	   
	    		   /* Store data in positionSample */
	    		   psample.setAltitude(java.lang.Float.parseFloat(sAltitude));
	    		   psample.setLatitude((float)dfLatDegrees);
	    		   psample.setLongitude((float)(dfLonDegrees));


	    		   /* Add the position sample to the datalog */
	    		  // psample.setDataLog(positionDataLog);
	    		  // psample.setDataLogId(positionDataLog.getDataLogId());
	    		   positionDataLog.getDataSamples().add(psample);
	    		   
	    		   /* Add the displacement sample to the datalog */
	    		   //dsample.setDataLog(displacementDataLog);
	    		   //dsample.setDataLogId(displacementDataLog.getDataLogId());
	    		   //displacementDataLog.add(dsample);
	    		   displacementDataLog.getDataSamples().add(dsample);
	    		  
	    		   }
	    		   catch (java.util.NoSuchElementException e)
	    		   {
	    			  // fei.setValid(true);
	    			  // fei.setFilename(filename);
	    			  // fei.setLine(i);
	    			  // eh.process(ErrorHandler.NOSUCHELEMENT_EXCEPTION,fei);
	    		   }
	    	   }
	       }
		 }
		 catch(IOException ex)
		 {
			// eh.process(ErrorHandler.FILEREAD_EXCEPTION,fei);
		 }
		 System.out.println(i+" GPS Samples Added.");
		 close();
		return(result);
	}

	  private void close()
	  {
		 // FileErrorInfo fei = new FileErrorInfo();
		try
		{
			  fis.close();
		}
		catch(IOException ex)
		{
			//eh.process(ErrorHandler.FILENOTCLOSED_EXCEPTION,fei);
		}  
	  }
	  
	  private int StringtoInt(String input)
	  {
		 // FileErrorInfo fei = new FileErrorInfo();
		  int result = 0;
		  try
		  {
		  result = Integer.valueOf(input).intValue();
		  }
		  catch(java.lang.NumberFormatException e)
		  {
			//  eh.process(ErrorHandler.NUMBERFORMAT_EXCEPTION,fei);
		  }
		  return(result);
	  }
	  
	


}
